package com.lineage.server.utils;

import com.eric.RandomMobDeleteTimer;
import com.eric.RandomMobTable;
import com.lineage.server.IdFactory;
import com.lineage.server.IdFactoryNpc;
import com.lineage.server.datatables.MapsTable;
import com.lineage.server.datatables.NpcTable;
import com.lineage.server.datatables.SkillsTable;
import com.lineage.server.datatables.SpawnRandomMobTable;
import com.lineage.server.datatables.SprTable;
import com.lineage.server.datatables.lock.FurnitureSpawnReading;
import com.lineage.server.model.Instance.L1CrockInstance;
import com.lineage.server.model.Instance.L1DeInstance;
import com.lineage.server.model.Instance.L1DoorInstance;
import com.lineage.server.model.Instance.L1EffectInstance;
import com.lineage.server.model.Instance.L1FieldObjectInstance;
import com.lineage.server.model.Instance.L1FurnitureInstance;
import com.lineage.server.model.Instance.L1IllusoryInstance;
import com.lineage.server.model.Instance.L1MonsterInstance;
import com.lineage.server.model.Instance.L1NpcInstance;
import com.lineage.server.model.Instance.L1PcInstance;
import com.lineage.server.model.Instance.L1SkinInstance;
import com.lineage.server.model.L1Character;
import com.lineage.server.model.L1Location;
import com.lineage.server.model.L1Object;
import com.lineage.server.model.map.L1Map;
import com.lineage.server.model.map.L1WorldMap;
import com.lineage.server.serverpackets.S_DoActionGFX;
import com.lineage.server.serverpackets.S_NPCPack;
import com.lineage.server.serverpackets.S_NPCPack_Eff;
import com.lineage.server.serverpackets.S_PacketBoxGree;
import com.lineage.server.serverpackets.S_ServerMessage;
import com.lineage.server.serverpackets.S_SystemMessage;
import com.lineage.server.serverpackets.ServerBasePacket;
import com.lineage.server.templates.DeName;
import com.lineage.server.templates.L1Furniture;
import com.lineage.server.templates.L1Npc;
import com.lineage.server.templates.L1QuestUser;
import com.lineage.server.thread.GeneralThreadPool;
import com.lineage.server.types.Point;
import com.lineage.server.world.World;
import com.lineage.server.world.WorldClan;
import com.lineage.server.world.WorldEffect;
import com.lineage.server.world.WorldQuest;
import java.util.Iterator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class L1SpawnUtil {
  private static final Log _log = LogFactory.getLog(L1SpawnUtil.class);
  
	// 正向
	private static final byte HEADING_TABLE_X[] = { 0, 1, 1, 1, 0, -1, -1, -1 };
	private static final byte HEADING_TABLE_Y[] = { -1, -1, 0, 1, 1, 1, 0, -1 };
  
  public static L1EffectInstance spawnTrueTargetEffect(int npcId, int time, L1Character cha, L1PcInstance user, int skiiId, int gfxid) {
    L1EffectInstance effect = null;
    try {
      L1NpcInstance npc = NpcTable.get().newNpcInstance(npcId);
      if (npc == null)
        return null; 
      effect = (L1EffectInstance)npc;
      effect.setId(IdFactoryNpc.get().nextId());
      effect.setGfxId(gfxid);
      effect.setTempCharGfx(gfxid);
      effect.setX(cha.getX());
      effect.setY(cha.getY());
      effect.setHomeX(cha.getX());
      effect.setHomeY(cha.getY());
      effect.setHeading(0);
      effect.setMap(cha.getMapId());
      effect.setSkillId(skiiId);
      effect.setFollowSpeed(cha);
      if (user != null) {
        effect.setMaster((L1Character)user);
        effect.set_showId(user.get_showId());
      } 
      World.get().storeObject((L1Object)effect);
      if (user.getClan() != null) {
        L1PcInstance[] onlinemembers = WorldClan.get().getClan(user.getClanname()).getOnlineClanMember();
        L1PcInstance[] array;
        int length = (array = onlinemembers).length;
        int i = 0;
        while (i < length) {
          L1PcInstance clanmember = array[i];
          effect.addKnownObject((L1Object)clanmember);
          clanmember.addKnownObject((L1Object)effect);
          clanmember.sendPackets((ServerBasePacket)new S_NPCPack_Eff(effect));
          clanmember.sendPackets((ServerBasePacket)new S_DoActionGFX(effect.getId(), 4));
          effect.onPerceive(clanmember);
          i++;
        } 
      } else {
        effect.addKnownObject((L1Object)user);
        user.addKnownObject((L1Object)effect);
        user.sendPackets((ServerBasePacket)new S_NPCPack_Eff(effect));
        user.sendPackets((ServerBasePacket)new S_DoActionGFX(effect.getId(), 4));
        effect.onPerceive(user);
      } 
      if (time > 0)
        effect.set_spawnTime(time); 
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
    return effect;
  }
  
  public static L1NpcInstance spawnS(L1Location loc, int npcId, int showid, int time, int heading) {
    try {
      L1NpcInstance npc = NpcTable.get().newNpcInstance(npcId);
      if (npc == null)
        return null; 
      npc.setId(IdFactoryNpc.get().nextId());
      npc.setMap(loc.getMap());
      npc.getLocation().set(loc);
      npc.setHomeX(npc.getX());
      npc.setHomeY(npc.getY());
      npc.setHeading(heading);
      npc.set_showId(showid);
      World.get().storeObject((L1Object)npc);
      if (time > 0)
        npc.set_spawnTime(time); 
      return npc;
    } catch (Exception e) {
      _log.error("依LOC位置召唤指定NPC(传回NPC讯息)发生异常: " + npcId, e);
      return null;
    } 
  }
  
  public static L1NpcInstance spawnRx(L1Location loc, int npcId, int showid, int r, int time) {
    try {
      L1NpcInstance npc = NpcTable.get().newNpcInstance(npcId);
      if (npc == null)
        return null; 
      npc.setId(IdFactoryNpc.get().nextId());
      npc.setMap(loc.getMap());
      if (r == 0) {
        npc.getLocation().set(loc);
      } else {
        int tryCount = 0;
        do {
          tryCount++;
          npc.setX(loc.getX() + (int)(Math.random() * r) - (int)(Math.random() * r));
          npc.setY(loc.getY() + (int)(Math.random() * r) - (int)(Math.random() * r));
          if (npc.getMap().isInMap((Point)npc.getLocation()) && npc.getMap().isPassable((Point)npc.getLocation(), (L1Character)npc))
            break; 
          Thread.sleep(2L);
        } while (tryCount < 50);
        if (tryCount >= 50)
          npc.getLocation().set(loc); 
      } 
      npc.setHomeX(npc.getX());
      npc.setHomeY(npc.getY());
      npc.setHeading(5);
      npc.set_showId(showid);
      L1QuestUser q = WorldQuest.get().get(showid);
      if (q != null)
        q.addNpc(npc); 
      World.get().storeObject((L1Object)npc);
      World.get().addVisibleObject((L1Object)npc);
      npc.turnOnOffLight();
      npc.startChat(0);
      if (time > 0)
        npc.set_spawnTime(time); 
      return npc;
    } catch (Exception e) {
      _log.error("依LOC位置召唤指定NPC(传回NPC讯息)发生异常: " + npcId, e);
      return null;
    } 
  }
  
  public static void spawnR(L1Location loc, int npcId, int showid, int randomRange) {
    L1SpawnUtil util = new L1SpawnUtil();
    util.spawnR(loc, npcId, showid, randomRange, 0);
  }
  
  public static void spawn(L1Furniture temp) {
    try {
      L1NpcInstance npc = NpcTable.get().newNpcInstance(temp.get_npcid());
      if (npc == null)
        return; 
      L1FurnitureInstance furniture = (L1FurnitureInstance)npc;
      furniture.setId(IdFactoryNpc.get().nextId());
      furniture.setMap(temp.get_mapid());
      furniture.setX(temp.get_locx());
      furniture.setY(temp.get_locy());
      furniture.setHomeX(furniture.getX());
      furniture.setHomeY(furniture.getY());
      furniture.setHeading(0);
      furniture.setItemObjId(temp.get_item_obj_id());
      World.get().storeObject((L1Object)furniture);
      World.get().addVisibleObject((L1Object)furniture);
    } catch (Exception e) {
      _log.error("执行家具召唤发生异常!", e);
    } 
  }
  
  public static L1FurnitureInstance spawn(L1PcInstance pc, int npcid, int itemObjectId) {
    try {
      L1NpcInstance npc = NpcTable.get().newNpcInstance(npcid);
      if (npc == null)
        return null; 
      L1FurnitureInstance furniture = (L1FurnitureInstance)npc;
      furniture.setId(IdFactoryNpc.get().nextId());
      furniture.setMap(pc.getMapId());
      if (pc.getHeading() == 0) {
        furniture.setX(pc.getX());
        furniture.setY(pc.getY() - 1);
      } else if (pc.getHeading() == 2) {
        furniture.setX(pc.getX() + 1);
        furniture.setY(pc.getY());
      } 
      furniture.setHomeX(furniture.getX());
      furniture.setHomeY(furniture.getY());
      furniture.setHeading(0);
      furniture.setItemObjId(itemObjectId);
      World.get().storeObject((L1Object)furniture);
      World.get().addVisibleObject((L1Object)furniture);
      FurnitureSpawnReading.get().insertFurniture(furniture);
      return furniture;
    } catch (Exception e) {
      _log.error("执行家具召唤发生异常!", e);
      return null;
    } 
  }
  
  public static L1NpcInstance spawn(int npcid, int x, int y, short m, int h) {
    return spawnT(npcid, x, y, m, h, 0);
  }
  
  public static L1NpcInstance spawnT(int npcid, int x, int y, short m, int h, int time) {
    try {
      L1NpcInstance npc = NpcTable.get().newNpcInstance(npcid);
      if (npc == null)
        return null; 
      npc.setId(IdFactoryNpc.get().nextId());
      npc.setMap(m);
      npc.setX(x);
      npc.setY(y);
      npc.setHomeX(npc.getX());
      npc.setHomeY(npc.getY());
      npc.setHeading(h);
      World.get().storeObject((L1Object)npc);
      World.get().addVisibleObject((L1Object)npc);
      npc.turnOnOffLight();
      npc.startChat(0);
      if (time > 0)
        npc.set_spawnTime(time); 
      return npc;
    } catch (Exception e) {
      _log.error("执行NPC召唤发生异常: " + npcid, e);
      return null;
    } 
  }
  
  public static L1IllusoryInstance spawn(L1PcInstance pc, L1Location loc, int h, int time) {
    try {
      L1NpcInstance npc = NpcTable.get().newNpcInstance(81003);
      if (npc == null)
        return null; 
      L1IllusoryInstance ill = (L1IllusoryInstance)npc;
      ill.setId(IdFactoryNpc.get().nextId());
      ill.setMap(loc.getMap());
      ill.setX(loc.getX());
      ill.setY(loc.getY());
      ill.setHomeX(ill.getX());
      ill.setHomeY(ill.getY());
      ill.setHeading(h);
      ill.setNameId("分身");
      ill.setTitle(String.valueOf(String.valueOf(pc.getName())) + " 的");
      ill.setMaster((L1Character)pc);
      ill.set_showId(pc.get_showId());
      L1QuestUser q = WorldQuest.get().get(pc.get_showId());
      if (q != null)
        q.addNpc(npc); 
      World.get().storeObject((L1Object)ill);
      World.get().addVisibleObject((L1Object)ill);
      if (time > 0)
        ill.set_spawnTime(time); 
      if (pc.getWeapon() != null) {
        ill.setStatus(pc.getWeapon().getItem().getType1());
        if (pc.getWeapon().getItem().getRange() != -1) {
          ill.set_ranged(2);
        } else {
          ill.set_ranged(10);
          ill.setBowActId(66);
        } 
      } 
      ill.setLevel((int)(pc.getLevel() * 0.7D));
      ill.setStr((int)(pc.getStr() * 0.7D));
      ill.setCon((int)(pc.getCon() * 0.7D));
      ill.setDex((int)(pc.getDex() * 0.7D));
      ill.setInt((int)(pc.getInt() * 0.7D));
      ill.setWis((int)(pc.getWis() * 0.7D));
      ill.setMaxMp(10);
      ill.setCurrentMpDirect(10);
      ill.setTempCharGfx(pc.getTempCharGfx());
      ill.setGfxId(pc.getGfxId());
      int attack = SprTable.get().getAttackSpeed(pc.getGfxId(), 1);
      int move = SprTable.get().getMoveSpeed(pc.getGfxId(), ill.getStatus());
      ill.setPassispeed(move);
      ill.setAtkspeed(attack);
      ill.setBraveSpeed(pc.getBraveSpeed());
      ill.setMoveSpeed(pc.getMoveSpeed());
      return ill;
    } catch (Exception e) {
      _log.error("执行分身召唤发生异常!", e);
      return null;
    } 
  }
  
  public static L1MonsterInstance spawnX(int npcid, L1Location loc, int show_id) {
    try {
      L1NpcInstance npc = NpcTable.get().newNpcInstance(npcid);
      if (npc == null)
        return null; 
      L1MonsterInstance mob = (L1MonsterInstance)npc;
      mob.setId(IdFactoryNpc.get().nextId());
      mob.setMap(loc.getMap());
      mob.setX(loc.getX());
      mob.setY(loc.getY());
      mob.setHomeX(mob.getX());
      mob.setHomeY(mob.getY());
      mob.set_showId(show_id);
      L1QuestUser q = WorldQuest.get().get(show_id);
      if (q != null)
        q.addNpc(npc); 
      mob.setMovementDistance(20);
      World.get().storeObject((L1Object)mob);
      World.get().addVisibleObject((L1Object)mob);
      return mob;
    } catch (Exception e) {
      _log.error("执行召唤救援发生异常!", e);
      return null;
    } 
  }
  
  public static L1MonsterInstance spawnParty(L1NpcInstance master, int npcid, L1Location loc) {
    try {
      L1NpcInstance npc = NpcTable.get().newNpcInstance(npcid);
      if (npc == null)
        return null; 
      L1MonsterInstance mob = (L1MonsterInstance)npc;
      mob.setId(IdFactoryNpc.get().nextId());
      mob.setMap(loc.getMap());
      mob.setX(loc.getX());
      mob.setY(loc.getY());
      mob.setHomeX(mob.getX());
      mob.setHomeY(mob.getY());
      mob.setHeading(master.getHeading());
      mob.setMaster((L1Character)master);
      mob.set_showId(master.get_showId());
      L1QuestUser q = WorldQuest.get().get(master.get_showId());
      if (q != null)
        q.addNpc(npc); 
      World.get().storeObject((L1Object)mob);
      World.get().addVisibleObject((L1Object)mob);
      return mob;
    } catch (Exception e) {
      _log.error("执行召唤指定队员发生异常!", e);
      return null;
    } 
  }
  
  public static L1NpcInstance spawn(int npcid, L1Location loc) {
    try {
      L1NpcInstance npc = NpcTable.get().newNpcInstance(npcid);
      if (npc == null)
        return null; 
      npc.setId(IdFactoryNpc.get().nextId());
      npc.setMap(loc.getMap());
      npc.setX(loc.getX());
      npc.setY(loc.getY());
      npc.setHomeX(npc.getX());
      npc.setHomeY(npc.getY());
      World.get().storeObject((L1Object)npc);
      World.get().addVisibleObject((L1Object)npc);
      npc.turnOnOffLight();
      npc.onNpcAI();
      return npc;
    } catch (Exception e) {
      _log.error("执行分身召唤发生异常!", e);
      return null;
    } 
  }
  
  public static L1NpcInstance spawn(int npcid, L1Location loc, int heading, int showId) {
    try {
      Iterator<L1PcInstance> iterator;
      L1NpcInstance npc = NpcTable.get().newNpcInstance(npcid);
      if (npc == null)
        return null; 
      npc.setId(IdFactoryNpc.get().nextId());
      npc.setMap(loc.getMap());
      npc.setX(loc.getX());
      npc.setY(loc.getY());
      npc.setHomeX(npc.getX());
      npc.setHomeY(npc.getY());
      npc.setHeading(heading);
      npc.set_showId(showId);
      L1QuestUser q = WorldQuest.get().get(showId);
      if (q != null)
        q.addNpc(npc); 
      World.get().storeObject((L1Object)npc);
      World.get().addVisibleObject((L1Object)npc);
      int gfx = npc.getTempCharGfx();
      switch (gfx) {
        case 7548:
        case 7550:
        case 7552:
        case 7554:
        case 7585:
        case 7591:
        case 7840:
        case 8096:
          npc.broadcastPacketAll((ServerBasePacket)new S_NPCPack(npc));
          npc.broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(npc.getId(), 11));
          break;
        case 7539:
        case 7557:
        case 7558:
        case 7864:
        case 7869:
        case 7870:
        case 8036:
        case 8054:
        case 8055:
          iterator = World.get().getVisiblePlayer((L1Object)npc, 50).iterator();
          while (iterator.hasNext()) {
            L1PcInstance _pc = iterator.next();
            if (npc.getTempCharGfx() == 7539) {
              _pc.sendPackets((ServerBasePacket)new S_ServerMessage(1570));
              continue;
            } 
            if (npc.getTempCharGfx() == 7864) {
              _pc.sendPackets((ServerBasePacket)new S_ServerMessage(1657));
              continue;
            } 
            if (npc.getTempCharGfx() != 8036)
              continue; 
            _pc.sendPackets((ServerBasePacket)new S_ServerMessage(1755));
          } 
          npc.broadcastPacketAll((ServerBasePacket)new S_NPCPack(npc));
          npc.broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(npc.getId(), 11));
          break;
        case 145:
        case 2158:
        case 3547:
        case 3566:
        case 3957:
        case 3969:
        case 3984:
        case 3989:
        case 7719:
        case 10071:
        case 11465:
        case 11467:
          npc.broadcastPacketAll((ServerBasePacket)new S_NPCPack(npc));
          npc.broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(npc.getId(), 4));
          break;
        case 30:
          npc.broadcastPacketAll((ServerBasePacket)new S_NPCPack(npc));
          npc.broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(npc.getId(), 30));
          break;
      } 
      npc.turnOnOffLight();
      return npc;
    } catch (Exception e) {
      _log.error("执行副本NPC召唤发生异常!", e);
      return null;
    } 
  }
  
  public static L1NpcInstance spawn1(int npcid, int x, int y, short m, int h, int gfxid, int time) {
    try {
      L1NpcInstance npc = NpcTable.get().newNpcInstance(npcid);
      if (npc == null)
        return null; 
      npc.setId(IdFactoryNpc.get().nextId());
      npc.setMap(m);
      npc.setX(x);
      npc.setY(y);
      npc.setHomeX(npc.getX());
      npc.setHomeY(npc.getY());
      npc.setHeading(h);
      npc.setTempCharGfx(gfxid);
      npc.setGfxId(gfxid);
      World.get().storeObject((L1Object)npc);
      World.get().addVisibleObject((L1Object)npc);
      npc.turnOnOffLight();
      npc.startChat(0);
      if (time > 0)
        npc.set_spawnTime(time); 
      return npc;
    } catch (Exception e) {
      _log.error("执行赌场参赛者NPC召唤发生异常: " + npcid, e);
      return null;
    } 
  }
  
  public static void doSpawnFireWall(L1Character cha, int targetX, int targetY) {
    L1SpawnUtil util = new L1SpawnUtil();
    util.doSpawnFireWallR(cha, targetX, targetY);
  }
  
  public static L1EffectInstance spawnEffect(int npcId, int time, int locX, int locY, short mapId, L1Character user, int skiiId) {
    L1EffectInstance effect = null;
    try {
      L1NpcInstance npc = NpcTable.get().newNpcInstance(npcId);
      if (npc == null)
        return null; 
      effect = (L1EffectInstance)npc;
      effect.setId(IdFactoryNpc.get().nextId());
      effect.setGfxId(effect.getGfxId());
      effect.setX(locX);
      effect.setY(locY);
      effect.setHomeX(locX);
      effect.setHomeY(locY);
      effect.setHeading(0);
      effect.setMap(mapId);
      if (user != null) {
        effect.setMaster(user);
        effect.set_showId(user.get_showId());
        L1QuestUser q = WorldQuest.get().get(user.get_showId());
        if (q != null)
          q.addNpc(npc); 
        if (effect.getNpcId() == 86126 && effect.getMapId() != 5153) {
          effect.setNameId(user.getName());
          effect.setTempLawful(user.getLawful());
        } 
      } 
      effect.setSkillId(skiiId);
      World.get().storeObject((L1Object)effect);
      World.get().addVisibleObject((L1Object)effect);
      effect.broadcastPacketAll((ServerBasePacket)new S_NPCPack_Eff(effect));
      if (effect.getGfxId() == 13600)
        effect.broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(npc.getId(), 4)); 
      Iterator<L1PcInstance> iterator = World.get().getRecognizePlayer((L1Object)effect).iterator();
      while (iterator.hasNext()) {
        L1PcInstance pc = iterator.next();
        effect.addKnownObject((L1Object)pc);
        pc.addKnownObject((L1Object)effect);
      } 
      if (time > 0)
        effect.set_spawnTime(time); 
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
    return effect;
  }
  
  public static L1DoorInstance spawnDoor(L1QuestUser quest, int doorId, int gfxid, int x, int y, short mapid, int direction) {
    L1Npc l1npc = NpcTable.get().getTemplate(81158);
    if (l1npc != null) {
      L1DoorInstance door = (L1DoorInstance)NpcTable.get().newNpcInstance(l1npc);
      int objid = IdFactoryNpc.get().nextId();
      door.setId(objid);
      door.setDoorId(doorId);
      door.setGfxId(gfxid);
      door.setX(x);
      door.setY(y);
      door.setMap(mapid);
      door.setHomeX(x);
      door.setHomeY(y);
      door.setDirection(direction);
      switch (gfxid) {
        case 89:
          door.setLeftEdgeLocation(y);
          door.setRightEdgeLocation(y);
          break;
        case 88:
          if (mapid == 9000) {
            door.setLeftEdgeLocation(x - 1);
            door.setRightEdgeLocation(x + 1);
            break;
          } 
          door.setLeftEdgeLocation(x - 1);
          door.setRightEdgeLocation(x + 1);
          break;
        case 90:
          door.setLeftEdgeLocation(x);
          door.setRightEdgeLocation(x + 1);
          break;
        case 7556:
          door.setLeftEdgeLocation(y - 1);
          door.setRightEdgeLocation(y + 3);
          break;
        case 7858:
        case 8011:
          door.setLeftEdgeLocation(x - 2);
          door.setRightEdgeLocation(x + 3);
          break;
        case 7859:
        case 8015:
        case 8019:
          door.setLeftEdgeLocation(y - 2);
          door.setRightEdgeLocation(y + 3);
          break;
        default:
          door.setLeftEdgeLocation(y);
          door.setRightEdgeLocation(y);
          break;
      } 
      door.setMaxHp(0);
      door.setCurrentHp(0);
      door.setKeeperId(0);
      if (quest != null) {
        door.set_showId(quest.get_id());
        quest.addNpc((L1NpcInstance)door);
      } 
      door.close();
      World.get().storeObject((L1Object)door);
      World.get().addVisibleObject((L1Object)door);
      return door;
    } 
    return null;
  }
  
  public static L1DeInstance spawn(int x, int y, int h, int mapid, int timeMillisToDelete) {
    try {
      L1Npc l1npc = NpcTable.get().getTemplate(81002);
      L1DeInstance npc = new L1DeInstance(l1npc, null);
      npc.setId(IdFactoryNpc.get().nextId());
      npc.setX(x);
      npc.setY(y);
      npc.setMap((short)mapid);
      npc.setHomeX(x);
      npc.setHomeY(y);
      npc.setHeading(h);
      L1Location loc = new L1Location(x, y, mapid);
      npc.getLocation().set(loc);
      World.get().storeObject((L1Object)npc);
      World.get().addVisibleObject((L1Object)npc);
      npc.turnOnOffLight();
      npc.startChat(0);
      if (timeMillisToDelete > 0)
        npc.set_spawnTime(timeMillisToDelete); 
      return npc;
    } catch (Exception e) {
      _log.error("执行DE召唤发生异常", e);
      return null;
    } 
  }
  
  public static L1DeInstance spawn(L1PcInstance pc, DeName de, int timeMillisToDelete) {
    try {
      L1Npc l1npc = NpcTable.get().getTemplate(81471);
      if (l1npc == null) {
        pc.sendPackets((ServerBasePacket)new S_SystemMessage("找不到该npc。"));
        return null;
      } 
      L1DeInstance npc = new L1DeInstance(l1npc, de);
      int randomRange = 5;
      npc.setId(IdFactoryNpc.get().nextId());
      npc.setMap(pc.getMapId());
      int tryCount = 0;
      do {
        tryCount++;
        npc.setX(pc.getX() + (int)(Math.random() * 5.0D) - (int)(Math.random() * 5.0D));
        npc.setY(pc.getY() + (int)(Math.random() * 5.0D) - (int)(Math.random() * 5.0D));
        if (npc.getMap().isInMap((Point)npc.getLocation()) && npc.getMap().isPassable((Point)npc.getLocation(), (L1Character)npc))
          break; 
        Thread.sleep(2L);
      } while (tryCount < 50);
      if (tryCount >= 50) {
        npc.getLocation().set(pc.getLocation());
        npc.getLocation().forward(pc.getHeading());
      } 
      npc.setHomeX(npc.getX());
      npc.setHomeY(npc.getY());
      npc.setHeading(pc.getHeading());
      npc.set_showId(pc.get_showId());
      L1QuestUser q = WorldQuest.get().get(pc.get_showId());
      if (q != null)
        q.addNpc((L1NpcInstance)npc); 
      World.get().storeObject((L1Object)npc);
      World.get().addVisibleObject((L1Object)npc);
      npc.turnOnOffLight();
      npc.startChat(0);
      if (timeMillisToDelete > 0)
        npc.set_spawnTime(timeMillisToDelete); 
      return npc;
    } catch (Exception e) {
      _log.error("执行DE召唤发生异常", e);
      return null;
    } 
  }
  
  public static L1FieldObjectInstance spawn(int showid, int gfxid, int x, int y, int map, int timeMillisToDelete) {
    try {
      L1FieldObjectInstance field = (L1FieldObjectInstance)NpcTable.get().newNpcInstance(71081);
      if (field != null) {
        field.setId(IdFactoryNpc.get().nextId());
        field.setGfxId(gfxid);
        field.setTempCharGfx(gfxid);
        field.setMap((short)map);
        field.setX(x);
        field.setY(y);
        field.setHomeX(x);
        field.setHomeY(y);
        field.setHeading(5);
        field.set_showId(showid);
        L1QuestUser q = WorldQuest.get().get(showid);
        if (q != null)
          q.addNpc((L1NpcInstance)field); 
        World.get().storeObject((L1Object)field);
        World.get().addVisibleObject((L1Object)field);
        if (timeMillisToDelete > 0)
          field.set_spawnTime(timeMillisToDelete); 
        return field;
      } 
    } catch (Exception e) {
      _log.error("执行景观(副本专用)召唤发生异常", e);
    } 
    return null;
  }
  
  public static L1NpcInstance spawn(int npcid, int x, int y, short m, int h, int gfxid) {
    try {
      L1NpcInstance npc = NpcTable.get().newNpcInstance(npcid);
      if (npc == null)
        return null; 
      npc.setId(IdFactoryNpc.get().nextId());
      npc.setMap(m);
      npc.setX(x);
      npc.setY(y);
      npc.setHomeX(npc.getX());
      npc.setHomeY(npc.getY());
      npc.setHeading(h);
      npc.setTempCharGfx(gfxid);
      npc.setGfxId(gfxid);
      World.get().storeObject((L1Object)npc);
      World.get().addVisibleObject((L1Object)npc);
      npc.turnOnOffLight();
      return npc;
    } catch (Exception e) {
      _log.error("执行NPC召唤发生异常: " + npcid, e);
      return null;
    } 
  }
  
  public static void spawn(L1PcInstance pc, int npcId, int r, int t) {
    L1SpawnUtil util = new L1SpawnUtil();
    util.spawnR(pc.getLocation(), npcId, pc.get_showId(), r, t);
  }
  
  public static void spawn(int randomMobId) {
    try {
      RandomMobTable mobTable = RandomMobTable.getInstance();
      int mobCont = mobTable.getCont(randomMobId);
      int mobId = mobTable.getMobId(randomMobId);
      L1NpcInstance[] npc = new L1NpcInstance[mobCont];
      int i = 0;
      while (i < mobCont) {
        short mapId = mobTable.getRandomMapId(randomMobId);
        int x = mobTable.getRandomMapX(mapId);
        int y = mobTable.getRandomMapY(mapId);
        npc[i] = NpcTable.get().newNpcInstance(mobId);
        NpcTable.get().newNpcInstance(mobId).setId(IdFactory.get().nextId());
        npc[i].setMap(mapId);
        int tryCount = 0;
        do {
          tryCount++;
          npc[i].setX(x + Random.nextInt(200) - Random.nextInt(200));
          npc[i].setY(y + Random.nextInt(200) - Random.nextInt(200));
          L1Map map = npc[i].getMap();
          if (map.isInMap((Point)npc[i].getLocation()) && map.isPassable((Point)npc[i].getLocation(), null))
            break; 
          Thread.sleep(1L);
        } while (tryCount < 50);
        if (tryCount >= 50) {
          boolean find = false;
          Iterator<L1Object> iterator = World.get().getVisibleObjects(mapId).values().iterator();
          while (iterator.hasNext()) {
            Object obj = iterator.next();
            if (obj instanceof L1PcInstance) {
              L1PcInstance findPc = (L1PcInstance)obj;
              npc[i].getLocation().set(findPc.getLocation());
              npc[i].getLocation().forward(findPc.getHeading());
              find = true;
              break;
            } 
          } 
        } 
        npc[i].setHomeX(npc[i].getX());
        npc[i].setHomeY(npc[i].getY());
        npc[i].setHeading(0);
        World.get().storeObject((L1Object)npc[i]);
        World.get().addVisibleObject((L1Object)npc[i]);
        npc[i].turnOnOffLight();
        npc[i].startChat(0);
        i++;
      } 
      int timeSecondToDelete = mobTable.getTimeSecondToDelete(randomMobId);
      if (timeSecondToDelete > 0) {
        RandomMobDeleteTimer timer = new RandomMobDeleteTimer(randomMobId, npc);
        timer.begin();
      } 
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  public static L1CrockInstance spawn(L1Location loc) {
    try {
      L1Npc l1npc = NpcTable.get().getTemplate(71254);
      if (l1npc == null) {
        _log.error("找不到该npc:71254");
        return null;
      } 
      L1CrockInstance npc = new L1CrockInstance(l1npc);
      npc.setId(IdFactoryNpc.get().nextId());
      npc.setMap(loc.getMap());
      npc.setX(loc.getX());
      npc.setY(loc.getY());
      npc.setHeading(5);
      npc.setHomeX(npc.getX());
      npc.setHomeY(npc.getY());
      World.get().storeObject((L1Object)npc);
      World.get().addVisibleObject((L1Object)npc);
      return npc;
    } catch (Exception e) {
      _log.error("执行召唤时空裂痕发生异常!", e);
      return null;
    } 
  }
  
  public static L1DeInstance spawnDE(L1PcInstance pc, DeName de, boolean home, int r, int timeMillisToDelete) {
    try {
      L1Npc l1npc = NpcTable.get().getTemplate(81471);
      if (l1npc == null) {
        pc.sendPackets((ServerBasePacket)new S_SystemMessage("找不到该npc。"));
        return null;
      } 
      L1DeInstance npc = new L1DeInstance(l1npc, de);
      npc.setId(IdFactoryNpc.get().nextId());
      npc.setMap(pc.getMapId());
      npc.setX(pc.getX());
      npc.setY(pc.getY());
      if (!home) {
        npc.setHomeX(0);
        npc.setHomeY(0);
      } else {
        npc.setHomeX(npc.getX());
        npc.setHomeY(npc.getY());
      } 
      npc.setHeading(pc.getHeading());
      npc.set_showId(pc.get_showId());
      L1QuestUser q = WorldQuest.get().get(pc.get_showId());
      if (q != null)
        q.addNpc((L1NpcInstance)npc); 
      World.get().storeObject((L1Object)npc);
      World.get().addVisibleObject((L1Object)npc);
      npc.turnOnOffLight();
      npc.startChat(0);
      if (timeMillisToDelete > 0)
        npc.set_spawnTime(timeMillisToDelete); 
      return npc;
    } catch (Exception e) {
      _log.error("执行DE召唤发生异常", e);
      return null;
    } 
  }
  
  public static L1SkinInstance spawnSkin(L1PcInstance pc, int gfxid) {
    try {
      L1NpcInstance npc = NpcTable.get().newNpcInstance(81001);
      if (npc == null)
        return null; 
      L1SkinInstance skin = (L1SkinInstance)npc;
      skin.setId(IdFactoryNpc.get().nextId());
      skin.setMap(pc.getMap());
      skin.setX(pc.getX());
      skin.setY(pc.getY());
      skin.setHomeX(pc.getX());
      skin.setHomeY(pc.getY());
      skin.setHeading(pc.getHeading());
      skin.setMaster((L1Character)pc);
      skin.set_showId(pc.get_showId());
      L1QuestUser q = WorldQuest.get().get(pc.get_showId());
      if (q != null)
        q.addNpc(npc); 
      World.get().storeObject((L1Object)skin);
      World.get().addVisibleObject((L1Object)skin);
      skin.setTempCharGfx(gfxid);
      skin.setGfxId(gfxid);
      int attack = SprTable.get().getAttackSpeed(gfxid, 1);
      int move = SprTable.get().getMoveSpeed(gfxid, skin.getStatus());
      skin.setPassispeed(move);
      skin.setAtkspeed(attack);
      skin.setBraveSpeed(pc.getBraveSpeed());
      skin.setMoveSpeed(pc.getMoveSpeed());
      return skin;
    } catch (Exception e) {
      _log.error("执行光圈召唤发生异常!", e);
      return null;
    } 
  }
  
  public static void spawnMob(int npcId, int x, int y, short mapid, int heading, int isCount) {
    try {
      L1NpcInstance npc = NpcTable.get().newNpcInstance(npcId);
      npc.setId(IdFactoryNpc.get().nextId());
      npc.setMap(mapid);
      if (isCount > 0) {
        npc.setNameId("远古" + npc.getNameId());
      } else {
        npc.setNameId(npc.getNameId());
      } 
      npc.setX(x);
      npc.setY(y);
      npc.setHomeX(x);
      npc.setHomeY(y);
      npc.setHeading(heading);
      World.get().storeObject((L1Object)npc);
      World.get().addVisibleObject((L1Object)npc);
      npc.startChat(0);
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  public static L1NpcInstance spawnai(int npcid, int x, int y, int h, int gfxid, int time) {
    try {
      L1NpcInstance npc = NpcTable.get().newNpcInstance(npcid);
      if (npc == null)
        return null; 
      npc.setId(IdFactoryNpc.get().nextId());
      npc.setMap(npc.getMapId());
      npc.setX(x);
      npc.setY(y);
      npc.setHomeX(npc.getX());
      npc.setHomeY(npc.getY());
      npc.setHeading(h);
      npc.setTempCharGfx(gfxid);
      npc.setGfxId(gfxid);
      World.get().storeObject((L1Object)npc);
      World.get().addVisibleObject((L1Object)npc);
      npc.turnOnOffLight();
      npc.startChat(0);
      if (time > 0)
        npc.set_spawnTime(time); 
      return npc;
    } catch (Exception e) {
      _log.error("执行NPC召唤发生异常: " + npcid, e);
      return null;
    } 
  }
  
  public static void spawnRandomMob(int randomMobId) {
    try {
      SpawnRandomMobTable mobTable = SpawnRandomMobTable.get();
      int mobCont = mobTable.getCont(randomMobId);
      int mobId = mobTable.getMobId(randomMobId);
      L1NpcInstance[] npc = new L1NpcInstance[mobCont];
      int i = 0;
      while (i < mobCont) {
        short mapId = mobTable.getRandomMapId(randomMobId);
        int x = mobTable.getRandomMapX(mapId);
        int y = mobTable.getRandomMapY(mapId);
        npc[i] = NpcTable.get().newNpcInstance(mobId);
        NpcTable.get().newNpcInstance(mobId).setId(IdFactoryNpc.get().nextId());
        npc[i].setMap(mapId);
        int tryCount = 0;
        do {
          tryCount++;
          npc[i].setX(x + Random.nextInt(200) - Random.nextInt(200));
          npc[i].setY(y + Random.nextInt(200) - Random.nextInt(200));
          L1Map map = npc[i].getMap();
          if (map.isInMap((Point)npc[i].getLocation()) && map.isPassable((Point)npc[i].getLocation(), (L1Character)npc[i]))
            break; 
          Thread.sleep(1L);
        } while (tryCount < 50);
        if (tryCount >= 50) {
          boolean find = false;
          Iterator<L1Object> iterator = World.get().getVisibleObjects(mapId).values().iterator();
          while (iterator.hasNext()) {
            Object obj = iterator.next();
            if (obj instanceof L1PcInstance) {
              L1PcInstance findPc = (L1PcInstance)obj;
              npc[i].getLocation().set(findPc.getLocation());
              npc[i].getLocation().forward(findPc.getHeading());
              find = true;
              break;
            } 
          } 
        } 
        npc[i].setHomeX(npc[i].getX());
        npc[i].setHomeY(npc[i].getY());
        npc[i].setHeading(0);
        World.get().storeObject((L1Object)npc[i]);
        World.get().addVisibleObject((L1Object)npc[i]);
        npc[i].startChat(0);
        int timeMillisToDelete = mobTable.getTimeSecondToDelete(randomMobId);
        if (timeMillisToDelete > 0)
          npc[i].set_spawnTime(timeMillisToDelete); 
        if (mobTable.isBroad(randomMobId))
          World.get().broadcastPacketToAll(
              (ServerBasePacket)new S_PacketBoxGree("【" + npc[i].getName() + "】出现在" + MapsTable.get().getMapName(mapId))); 
        _log.info("随机生怪->【" + npc[i].getName() + "】出现在" + MapsTable.get().getMapName(mapId));
        i++;
      } 
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  private void spawnR(L1Location loc, int npcId, int showid, int randomRange, int timeMillisToDelete) {
    SpawnR1 spawn = new SpawnR1(loc, npcId, showid, randomRange, timeMillisToDelete);
    GeneralThreadPool.get().schedule(spawn, 0L);
  }
  
  public void doSpawnFireWallR(L1Character cha, int targetX, int targetY) {
    SpawnR2 spawn = new SpawnR2(cha, targetX, targetY);
    GeneralThreadPool.get().schedule(spawn, 0L);
  }
  
  private class SpawnR1 implements Runnable {
    final L1Location _location;
    
    final int _npcId;
    
    final int _showid;
    
    final int _randomRange;
    
    final int _timeMillisToDelete;
    
    private SpawnR1(L1Location location, int npcId, int showid, int randomRange, int timeMillisToDelete) {
      this._location = location;
      this._npcId = npcId;
      this._showid = showid;
      this._randomRange = randomRange;
      this._timeMillisToDelete = timeMillisToDelete;
    }
    
    public void run() {
      try {
        Iterator<L1PcInstance> iterator;
        L1NpcInstance npc = NpcTable.get().newNpcInstance(this._npcId);
        if (npc == null)
          return; 
        npc.setId(IdFactoryNpc.get().nextId());
        npc.setMap(this._location.getMap());
        if (this._randomRange == 0) {
          npc.getLocation().set(this._location);
        } else {
          int tryCount = 0;
          do {
            tryCount++;
            npc.setX(this._location.getX() + (int)(Math.random() * this._randomRange) - 
                (int)(Math.random() * this._randomRange));
            npc.setY(this._location.getY() + (int)(Math.random() * this._randomRange) - 
                (int)(Math.random() * this._randomRange));
            if (npc.getMap().isInMap((Point)npc.getLocation()) && 
              npc.getMap().isPassable((Point)npc.getLocation(), (L1Character)npc))
              break; 
            Thread.sleep(2L);
          } while (tryCount < 50);
          if (tryCount >= 50)
            npc.getLocation().set(this._location); 
        } 
        npc.setHomeX(npc.getX());
        npc.setHomeY(npc.getY());
        npc.setHeading(5);
        npc.set_showId(this._showid);
        L1QuestUser q = WorldQuest.get().get(this._showid);
        if (q != null)
          q.addNpc(npc); 
        World.get().storeObject((L1Object)npc);
        World.get().addVisibleObject((L1Object)npc);
        int gfx = npc.getTempCharGfx();
        switch (gfx) {
          case 7548:
          case 7550:
          case 7552:
          case 7554:
          case 7585:
          case 7591:
          case 7840:
          case 8096:
            npc.broadcastPacketAll((ServerBasePacket)new S_NPCPack(npc));
            npc.broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(npc.getId(), 11));
            break;
          case 7539:
          case 7557:
          case 7558:
          case 7864:
          case 7869:
          case 7870:
          case 8036:
          case 8054:
          case 8055:
            iterator = World.get().getVisiblePlayer((L1Object)npc, 50).iterator();
            while (iterator.hasNext()) {
              L1PcInstance _pc = iterator.next();
              if (npc.getTempCharGfx() == 7539) {
                _pc.sendPackets((ServerBasePacket)new S_ServerMessage(1570));
                continue;
              } 
              if (npc.getTempCharGfx() == 7864) {
                _pc.sendPackets((ServerBasePacket)new S_ServerMessage(1657));
                continue;
              } 
              if (npc.getTempCharGfx() != 8036)
                continue; 
              _pc.sendPackets((ServerBasePacket)new S_ServerMessage(1755));
            } 
            npc.broadcastPacketAll((ServerBasePacket)new S_NPCPack(npc));
            npc.broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(npc.getId(), 11));
            break;
          case 145:
          case 2158:
          case 3547:
          case 3566:
          case 3957:
          case 3969:
          case 3984:
          case 3989:
          case 7719:
          case 10071:
          case 11465:
          case 11467:
            npc.broadcastPacketAll((ServerBasePacket)new S_NPCPack(npc));
            npc.broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(npc.getId(), 4));
            break;
          case 30:
            npc.broadcastPacketAll((ServerBasePacket)new S_NPCPack(npc));
            npc.broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(npc.getId(), 30));
            break;
        } 
        npc.turnOnOffLight();
        npc.startChat(0);
        if (this._timeMillisToDelete > 0)
          npc.set_spawnTime(this._timeMillisToDelete); 
      } catch (Exception e) {
        L1SpawnUtil._log.error("执行NPC召唤发生异常: " + this._npcId, e);
      } 
    }
  }
  
  private class SpawnR2 implements Runnable {
    private final L1Character _cha;
    
    private final int _targetX;
    
    private final int _targetY;
    
    private SpawnR2(L1Character cha, int targetX, int targetY) {
      this._cha = cha;
      this._targetX = targetX;
      this._targetY = targetY;
    }
    
    public void run() {
      try {
        int npcid = 81157;
        L1Npc firewall = NpcTable.get().getTemplate(81157);
        int duration = SkillsTable.get().getTemplate(58).getBuffDuration();
        if (firewall == null)
          return; 
        L1Character base = this._cha;
        int i = 0;
        while (i < 8) {
          Thread.sleep(2L);
          int tmp = 0;
          Iterator<L1Object> iterator = World.get().getVisibleObjects((L1Object)this._cha).iterator();
          while (iterator.hasNext()) {
            L1Object objects = iterator.next();
            if (objects == null)
              continue; 
            if (!(objects instanceof L1EffectInstance))
              continue; 
            L1EffectInstance effect = (L1EffectInstance)objects;
            if (this._cha == null || !effect.getMaster().equals(this._cha))
              continue; 
            tmp++;
          } 
          if (tmp >= 24)
            return; 
          int a = base.targetDirection(this._targetX, this._targetY);
          int x = base.getX();
          int y = base.getY();
          x += L1SpawnUtil.HEADING_TABLE_X[a];
          y += L1SpawnUtil.HEADING_TABLE_Y[a];
          if (!base.isAttackPosition(x, y, 1)) {
            x = base.getX();
            y = base.getY();
          } 
          L1Location loc = new L1Location(x, y, this._cha.getMapId());
          if (!WorldEffect.get().isEffect(loc, 81157)) {
            L1Map map = L1WorldMap.get().getMap(this._cha.getMapId());
            if (!map.isArrowPassable(x, y, this._cha.getHeading()))
              break; 
            if (this._cha instanceof L1PcInstance) {
              L1PcInstance user = (L1PcInstance)this._cha;
              L1EffectInstance l1EffectInstance = L1SpawnUtil.spawnEffect(81157, duration, x, y, user.getMapId(), (L1Character)user, 58);
            } else {
              L1EffectInstance l1EffectInstance = L1SpawnUtil.spawnEffect(81157, duration, x, y, this._cha.getMapId(), null, 58);
            } 
          } 
          i++;
        } 
      } catch (Exception e) {
        L1SpawnUtil._log.error(e.getLocalizedMessage(), e);
      } 
    }
  }
}
